#include <iostream>
#include <boost/filesystem/path.hpp>
#include <string>
#include <fstream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include "CmdLine/cmdargs.h"
#include "get_arg.h"
using std::string;
using std::ofstream;
using std::ifstream;
using std::fstream;
using std::cerr;
using std::cout;




//_______________________________________________________________________________________

//		process_command_line_options

//				from command line
//				Created [9/13/2001]

//_______________________________________________________________________________________
bool process_command_line_options(int argc, char* argv[], t_program_args& args)
{
	// optional help directive
	CmdArgUsage opt_help('h', "help", 	"display this message", &cerr);

	// required options
	// const unsigned REQUIRED = CmdArg::isREQ | CmdArg::isVALREQ;
	CmdArgStr opt_output_prefix	('p', "prefix", "<string>",
								"Output files will have the supplied strings as a prefix. "
								"This can include the relative or absolute file path.");
	CmdArgStr opt_taxon1		('a', "a_species", "<string>",
								"Regular expression to identify species A sequences. "
								"Defaults to ENSMUS.");
	CmdArgStr opt_taxon2		('b', "b_species", "<string>",
								"Regular expression to identify species B sequences."
								"Defaults to ENSRNO.");
	CmdArgSet opt_fill_lacunae	('n', "nulls",
								"Replace null or out of range values (lacunae) values with "
								"values extrapolated from ultrametric properties.");
	CmdArgInt opt_keyhole_size	('k', "keyhole_optimization_size", "number",
								"When using Kitsch to optimise UPGMA trees, the maximum "
								"subbranch size to optimize at one go.");
	CmdArgInt opt_cnt_iterative_fitch_passes
								('r', "random_fitch_passes", "number",
								"When using Kitsch/Fitch, how many times the data should be "
								"randomly reordered to search for the global optimum.");
	CmdArgFloat opt_power		('w', "weighting_falloff", "<double>",
								"for weights in Kitch = nth power of the denominator. "
								"If > 2, the weighting of errors will fall off sharply "
								"for greater distances.");
	CmdArgSet opt_upgma			('U', "UPGMA",
								"(Default)Use UPGMA rather than Fitsch with contempraneous tips.");
	CmdArgSet opt_kitsch		('K', "KITSCH",
								"Use Fitsch with contempraneous tips rather than UPGMA.");
	CmdArgSet opt_optimize_kitsch('O', "Optimize_using_kitsch",
								"Use Fitsch with contempraneous tips on top of UPGMA.");
	CmdArgStr opt_ks_file		("[ks_distance_file]",
								"Tab delimited file with Ks distances.");
	CmdArgSet opt_verbose		('v', "verbose","issue lots more messages.");
	
	opt_fill_lacunae = false;
	opt_upgma = true;
	opt_kitsch = false;
	opt_optimize_kitsch = false;
	opt_keyhole_size	= 40;
	opt_power			= -1.0;
	
	
	
	string exe_file_name =  boost::filesystem::path(*argv).leaf();
	
	// construct command line
	CmdLine  cmdline(exe_file_name.c_str(),
							&opt_output_prefix,
							&opt_taxon1,
							&opt_taxon2,
							&opt_fill_lacunae,
							&opt_upgma,
							&opt_kitsch,
							&opt_ks_file,
							&opt_keyhole_size,
							&opt_optimize_kitsch,
							&opt_cnt_iterative_fitch_passes,
							&opt_power,
							&opt_help,
							&opt_verbose,
							0);
	cmdline.description(
		"This programme takes Ks distances from either STDIN or the command line "
		"and resolves the phylogenetic tree of one or more group of paralogs.\n\n"
		
		"Ks distances are supplied in tab delimited file in three column format: "
			"gene1 gene2 Ks_distance.");

	// parse command line
	CmdArgvIter  argv_iter(--argc, ++argv);
	// report command line errors
	if (cmdline.parse(argv_iter))
		return false;

	// define verbose first before any error messages generated
	args.verbose	= opt_verbose;
	
	args.taxon1				= opt_taxon1;
	args.taxon2				= opt_taxon2;
	if (!args.taxon1.length())
		 args.taxon1 = "ENSMUS";
	if (!args.taxon2.length())
		 args.taxon2 = "ENSRNO";
	args.fill_lacunae		= opt_fill_lacunae;
	
	if (opt_optimize_kitsch)
	{
		args.analysis_type	= eUPGMA_KITSCH;
	}
	else
	if (opt_kitsch)
	{
		args.analysis_type	= eKITSCH;	
	}
	else
	{
		args.analysis_type	= eUPGMA;
	}
	args.ks_file			= opt_ks_file;
	args.out_file_prefix	= opt_output_prefix;
	
	// cnt_iterative_fitch_passes
	args.cnt_iterative_fitch_passes = (opt_cnt_iterative_fitch_passes > 0) ?
										std::min(opt_cnt_iterative_fitch_passes, 5000) :
										10;
	args.keyhole_size		= (opt_keyhole_size > 5) ? opt_keyhole_size : 5;
	args.keyhole_size		= std::min (args.keyhole_size, 5000U);
	args.power				= opt_power;
	if (args.power< 0.0)
		args.power= 2.0;
	return true;
}






